﻿//  Copyright © Decebal Mihailescu 2013-2014
//  All rights reserved. This source code and binaries are distributed under 
//  Microsoft Public PatternLicense (Ms-PL)
//  The latest code is available at http://VSDesignPatterns.codeplex.com

//  Redistributions of source code must retain the above copyright notice, 
//  this list of conditions and the following disclaimer. 
//  Redistributions in binary form must reproduce the above copyright notice, 
//  this list of conditions and the following disclaimer in the documentation 
//  and/or other materials provided with the distribution. 

//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER 
//  REMAINS UNCHANGED.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace DesignPatternsWizard
{
    using Common;
    interface IPageWizard : IServiceProvider
    {
        EventValidaton Validate(int index, ILanguageProvider ilp);

    }
    public class PageWizard : TabPage, IPageWizard
    {
        ITabWizard _parentTabWizard;

        #region IServiceProvider Members
        public new object GetService(Type serviceType)
        {
            if (serviceType == typeof(IPageWizard) || serviceType == typeof(IServiceProvider))
                return this;
            object res = null;
            res = (_parentTabWizard == null) ? null : _parentTabWizard.GetService(serviceType);
            if (res != null)
                return res;
            res = base.GetService(serviceType);

            return res;
        }

        #endregion

        protected override void OnParentChanged(EventArgs e)
        {
            _parentTabWizard = this.Parent as ITabWizard;
            base.OnParentChanged(e);
        }
        #region IWizardPage Members

        public EventValidaton Validate(int index, ILanguageProvider ilp)
        {
            EventValidaton evval = new EventValidaton() { SelIndex = index, Files = null, LangProvider = ilp };
            ITemplatePattern tg = this._parentTabWizard.SelectedPattern;//.SelectTemplate(null, null, null);
            if (tg == null)
            {
                evval.Result = ResultEnum.MissingFileTemplate;
                evval.ErrorMsg = "Corrupted pattern template";
                return evval;
            }
            if (tg.TemplateFiles == null)
            {
                try
                {
                    evval.Result = ResultEnum.UnlicensedLanguageProvider;
                    IWizardWindow iww = this._parentTabWizard.GetAsService<IWizardWindow>();
                    //this is because of a bug that does not allow the TemplateFiles to reload
                    evval.ErrorMsg = tg.CanGeneratePattern(iww) ? "Unlicensed pattern template.Restarting Visual Studio might fix it." : "Unlicensed pattern template";
                }
                catch 
                {
                     evval.ErrorMsg = "Unlicensed pattern template";
                }
                return evval;
            }
            if (tg.TemplateFiles.Any(t => t.FileTemplateContent == null))
            {
                ITemplateFile itf = tg.TemplateFiles.FirstOrDefault(t => t.FileTemplateContent == null);
                if (itf == null)
                {
                    evval.ErrorMsg = "Some File templates are missing";
                }
                else
                    evval.ErrorMsg = string.Format("'{0}' template file is missing", itf.FileTemplate);
                evval.Result = ResultEnum.MissingFileTemplate;

                return evval;
            }
            evval.Files = tg.TemplateFiles.Select(t => t.FileItemName);
            IProjectInfo ipi = ilp.GetAsService<IProjectInfo>();
            ipi.OnValidatePattern(this, evval);
            return evval;
        }

        #endregion
    }
    public class TabWizard : TabControl, ITabWizard
    {
        IPageWizard _crtPage;
        public IEnumerable<ITemplatePattern> Templates { get; set; }
        public ITemplatePattern SelectedPattern { get; set; }
        public TabWizard()
        {


        }
        protected override void OnParentChanged(EventArgs e)
        {
            if (DesignMode)
            {
                base.OnParentChanged(e);
                return;
            }

            _parentWnd = this.Parent as IWizardWindow;
            base.OnParentChanged(e);
        }
        protected override void OnSelecting(TabControlCancelEventArgs e)
        {
            if (DesignMode)
                base.OnSelecting(e);
            return;
        }
        protected override void OnSelected(TabControlEventArgs e)
        {
            if (DesignMode)
            {
                base.OnSelected(e);
                return;
            }
            _crtPage = e.TabPage as IPageWizard;

            base.OnSelected(e);
        }
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x00001328:// Hide tabs by trapping the TCM_ADJUSTRECT message
                    if (!DesignMode)
                    {
                        m.Result = (IntPtr)1;
                        return;
                    }
                    break;
                case (int)Msg.WM_DESTROY:
                    break;
                default: break;
            }
            base.WndProc(ref m);
        }

        protected override void OnKeyDown(KeyEventArgs ke)
        {
            // Block Ctrl+Tab and Ctrl+Shift+Tab hotkeys
            if (ke.Control && ke.KeyCode == Keys.Tab)
                return;
            base.OnKeyDown(ke);
        }

        protected override void OnValidating(System.ComponentModel.CancelEventArgs e)
        {
            if (DesignMode)
            {
                base.OnValidating(e);
                return;
            }
            base.OnValidating(e);

        }

        protected IWizardWindow _parentWnd;
        #region IServiceProvider Members

        public new object GetService(Type serviceType)
        {
            if (serviceType == typeof(ITabWizard) || serviceType == typeof(IServiceProvider))
                return this;
            object res = null;
            res = (_parentWnd == null) ? null : _parentWnd.GetService(serviceType);
            if (serviceType == typeof(IPageWizard))
                res = (this.SelectedTab == null) ? null : (SelectedTab as IServiceProvider).GetService(serviceType);
            if (res == null)
                res = base.GetService(serviceType);
            return res;
        }

        #endregion



    }


}
